﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Bystd.Geo.Geometries
{
    public class GeoLinestring:Geometry
    {
        public Coordinate this[int index]
        {
            get { return GetSequence(0, 0)[index]; }
        }

        public List<GeoLineSegment> GetLineSegments => CoordsToLineSegments();

        public GeoLinestring(GeoSequence sequence)
            :base(GeoType.LINESTRING,sequence)
        {

        }

        public GeoLinestring(string wktString)
            :base(GeoType.LINESTRING,wktString)
        {
           
        }

        public GeoLinestring(Coordinate[] coords)
            : base(GeoType.LINESTRING,coords)
        {
            
        }

        public GeoLinestring(GeoLinestring linestring)
            : base( GeoType.LINESTRING,linestring)
        {
             
        }

        public GeoLinestring(GeoPoint[] geoPoints)
            : base(GeoType.LINESTRING,geoPoints)
        {
            
        }

        public GeoLinestring(GeoLineSegment[] lineSegments)
            : base(lineSegments)
        {

        }

        private List<GeoLineSegment> CoordsToLineSegments()
        {
            var geo = GetSequence(0, 0);
            int lines = geo.Count;
            var segments = new List<GeoLineSegment>(lines);

            for (int i = 0; i < lines; ++i)
            {
                segments.Add(new GeoLineSegment(geo[i], geo[i + 1]));
            }

            return segments;
        }

        public GeoLineSegment GetBoundaryBox()
        {
            var geo = GetSequence(0, 0);
            var min =geo[0];
            var max = min;

            for (int i = 1; i < geo.Count; ++i)
            {
                if (min > geo[i]) min = geo[i];
                if (max < geo[i]) max = geo[i];
            }

            return new GeoLineSegment (min, max);
        }

        public bool Contains(Coordinate coord)
        {
            bool isContains = false;
            int cnt =GetSequence(0, 0).Count - 1;
            for (int i = 0; i < cnt; ++i)
            {
                isContains = new GeoLineSegment(GetSequence(0, 0)[i], GetSequence(0, 0)[i + 1]).Contains(coord);
                if (isContains) return true;
            }
            return false;
        }

        public double GeoLength()
        {
            double length = 0;
            var geo = GetSequence(0, 0);
            int len = geo.Count - 1;
            for (int i = 0; i < len; ++i)
            {
                length +=geo[i].Distance(geo[i + 1]);
            }
            return length;
        }

        public bool IsRing()
        {
            return GetSequence(0, 0).IsRing();
        }
    }
}
